﻿using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;


namespace MN.Framework.Security
{
    public class CryptoService
    {
        private const int TokenBytesLength = 13;

        //public string CreateSalt()
        //{
        //    var data = new byte[0x10];

        //    using (var crypto = new RNGCryptoServiceProvider())
        //    {
        //        crypto.GetBytes(data);

        //        return Convert.ToBase64String(data);
        //    }
        //}

        //public string CreateToken(string value)
        //{
        //    var token = new byte[TokenBytesLength];
        //    var userNameBytes = Encoding.Default.GetBytes(value);

        //    using(var crypto = new RNGCryptoServiceProvider())
        //    {
        //        crypto.GetBytes(token);
        //        var tokenBytes = token.Concat(userNameBytes)
        //                              .ToArray();

        //        return Convert.ToBase64String(tokenBytes);
        //    }
        //}

        public string GetValueFromToken(string token)
        {
            var tokenBytes = Convert.FromBase64String(token);
            var valueBytes = tokenBytes.Skip(TokenBytesLength)
                                       .ToArray();

            return Encoding.Default.GetString(valueBytes);
        }

        //public string Encrypt(string str)
        //{
        //    for (int i = 0; i < str.Length; i++)
        //    {

        //    }
        //    return str.Replace("l", "_o_").Replace('s', 'z').Replace(str[0], str[str.Length - 1]);
        //}
        //public string Decrypt(string str)
        //{
        //    return str.Replace('o', 'l').Replace('z', 's').Replace(str[str.Length - 1], str[0]);
        //}
        public static string Encrypt(string strToEncrypt, string strKey)
        {
            try
            {
                TripleDESCryptoServiceProvider objDESCrypto =
                    new TripleDESCryptoServiceProvider();
                MD5CryptoServiceProvider objHashMD5 = new MD5CryptoServiceProvider();
                byte[] byteHash, byteBuff;
                string strTempKey = strKey;
                byteHash = objHashMD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(strTempKey));
                objHashMD5 = null;
                objDESCrypto.Key = byteHash;
                objDESCrypto.Mode = CipherMode.ECB; //CBC, CFB
                byteBuff = ASCIIEncoding.ASCII.GetBytes(strToEncrypt);
                return Convert.ToBase64String(objDESCrypto.CreateEncryptor().
                    TransformFinalBlock(byteBuff, 0, byteBuff.Length));
            }
            catch (Exception ex)
            {
                return "Wrong Input. " + ex.Message;
            }
        }

        /// <summary>
        /// Decrypt the given string using the specified key.
        /// </summary>
        /// <param name="strEncrypted">The string to be decrypted.</param>
        /// <param name="strKey">The decryption key.</param>
        /// <returns>The decrypted string.</returns>
        public static string Decrypt(string strEncrypted, string strKey)
        {
            try
            {
                TripleDESCryptoServiceProvider objDESCrypto =
                    new TripleDESCryptoServiceProvider();
                MD5CryptoServiceProvider objHashMD5 = new MD5CryptoServiceProvider();
                byte[] byteHash, byteBuff;
                string strTempKey = strKey;
                byteHash = objHashMD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(strTempKey));
                objHashMD5 = null;
                objDESCrypto.Key = byteHash;
                objDESCrypto.Mode = CipherMode.ECB; //CBC, CFB
                byteBuff = Convert.FromBase64String(strEncrypted);
                string strDecrypted = ASCIIEncoding.ASCII.GetString
                (objDESCrypto.CreateDecryptor().TransformFinalBlock
                (byteBuff, 0, byteBuff.Length));
                objDESCrypto = null;
                return strDecrypted;
            }
            catch (Exception ex)
            {
                return "Wrong Input. " + ex.Message;
            }
        }

    }
}